/*
 * Copyright (C) 2008 Rob Cash
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 * 	http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 * ScheduleEditor.java
 *
 * Created on Dec 30, 2008, 11:59:39 AM
 */

package org.robcash.apps.messagepopup.view.components;

import static org.robcash.apps.messagepopup.vo.Schedule.EVERY_DAY;
import static org.robcash.apps.messagepopup.vo.Schedule.WEEKDAYS;
import static org.robcash.apps.messagepopup.vo.Schedule.SUNDAY;
import static org.robcash.apps.messagepopup.vo.Schedule.MONDAY;
import static org.robcash.apps.messagepopup.vo.Schedule.TUESDAY;
import static org.robcash.apps.messagepopup.vo.Schedule.WEDNESDAY;
import static org.robcash.apps.messagepopup.vo.Schedule.THURSDAY;
import static org.robcash.apps.messagepopup.vo.Schedule.FRIDAY;
import static org.robcash.apps.messagepopup.vo.Schedule.SATURDAY;

import java.util.Date;
import java.util.HashSet;
import java.util.Set;
import javax.swing.DefaultComboBoxModel;
import org.jdesktop.application.Application;
import org.jdesktop.application.ResourceMap;
import org.robcash.apps.messagepopup.Main;
import org.robcash.apps.messagepopup.vo.Schedule;
import org.robcash.apps.messagepopup.vo.SchedulePeriod;
import org.robcash.commons.swing.wizard.WizardComponent;

/**
 *
 * @author Rob
 */
public class ScheduleEditor extends WizardComponent {

    /**
     * All days
     */
    private static final String EVERY_DAY_BUTTON = "all";

    /**
     * Weekdays
     */
    private static final String WEEKDAYS_BUTTON = "weekdays";

    /**
     * Custom days
     */
    private static final String CUSTOM_DAYS_BUTTON = "custom";

    /**
     * Schedule
     */
    private Schedule schedule;

    /**
     * Period Intervals
     */
    private DefaultComboBoxModel periodIntervals;

    /**
     * Value of schedule name text field prior to editing
     */
    private String preEditScheduleName;

    /**
     * Indicates that a new schedule is being set
     */
    private boolean scheduleBeingSet = false;

    /** Creates new form ScheduleEditor */
    public ScheduleEditor() {
        ResourceMap resourceMap = Application.getInstance(Main.class).getContext().getResourceMap(ScheduleEditor.class);
        this.periodIntervals = new DefaultComboBoxModel();
        periodIntervals.addElement(
                new SchedulePeriod(5, resourceMap.getString("period.fiveMinutes")));
        periodIntervals.addElement(
                new SchedulePeriod(15, resourceMap.getString("period.fifteenMinutes")));
        periodIntervals.addElement(
                new SchedulePeriod(30, resourceMap.getString("period.thirtyMinutes")));
        periodIntervals.addElement(
                new SchedulePeriod(60, resourceMap.getString("period.hour")));
        periodIntervals.addElement(
                new SchedulePeriod(120, resourceMap.getString("period.twoHours")));
        periodIntervals.addElement(
                new SchedulePeriod(1440, resourceMap.getString("period.day")));
        initComponents();
    }

    /**
     * Get the current schedule
     * @return Schedule
     */
    public Schedule getSchedule() {
        return schedule;
    }

    /**
     * Set the schedule
     * @param schedule Schedule to model
     */
    public void setSchedule(Schedule schedule) {
        scheduleBeingSet = true;
        this.schedule = schedule;
        try {
            if ( schedule != null ) {
                nameTextField.setText(schedule.getName());
                setDays(schedule.getDays());
                startTimeSpinner.setValue(schedule.getStartTime());
                endTimeSpinner.setValue(schedule.getEndTime());
                frequencySpinner.setValue(schedule.getFrequency());
                for( int index = 0; index < periodIntervals.getSize(); index++ ) {
                    SchedulePeriod period = (SchedulePeriod) periodIntervals.getElementAt(index);
                    if ( period.getPeriod() == schedule.getPeriod() ) {
                        periodIntervals.setSelectedItem(period);
                        break;
                    }
                }
            }
        }
        finally {
            scheduleBeingSet = false;
        }
    }

    /**
     * Apply pending changes to schedule being edited
     */
    public void applyPendingChanges() {
        schedule.setName(nameTextField.getText());
        schedule.setStartTime((Date) startTimeSpinner.getValue());
        schedule.setEndTime((Date) endTimeSpinner.getValue());
        schedule.setPeriod(
                ((SchedulePeriod) frequencyComboBox.getSelectedItem()).getPeriod());
        schedule.setFrequency((Integer) frequencySpinner.getValue());
        Set<Integer> days = new HashSet<Integer>();
        if ( everyDayRadioButton.isSelected() ) {
            days.addAll(EVERY_DAY);
        }
        else if ( weekdayRadioButton.isSelected() ) {
            days.addAll(WEEKDAYS);
        }
        else {
            if ( sunCheckBox.isSelected() ) {
                days.add(SUNDAY);
            }
            if ( monCheckBox.isSelected() ) {
                days.add(MONDAY);
            }
            if ( tueCheckBox.isSelected() ) {
                days.add(TUESDAY);
            }
            if ( wedCheckBox.isSelected() ) {
                days.add(WEDNESDAY);
            }
            if ( thuCheckBox.isSelected() ) {
                days.add(THURSDAY);
            }
            if ( friCheckBox.isSelected() ) {
                days.add(FRIDAY);
            }
            if ( satCheckBox.isSelected() ) {
                days.add(SATURDAY);
            }

        }
        schedule.setDays(days);
    }

    /**
     * Enable or disable the editor
     * @param enabled Indicates if editing should be enabled (true) or
     * disabled (false)
     */
    @Override
    public void setEnabled(boolean enabled) {
        nameTextField.setEnabled(enabled);
        everyDayRadioButton.setEnabled(enabled);
        weekdayRadioButton.setEnabled(enabled);
        customRadioButton.setEnabled(enabled);
        frequencySpinner.setEnabled(enabled);
        frequencyComboBox.setEnabled(enabled);
        startTimeSpinner.setEnabled(enabled);
        endTimeSpinner.setEnabled(enabled);
        super.setEnabled(enabled);
    }

    protected void setDays(Set<Integer> days) {
        sunCheckBox.setSelected(false);
        monCheckBox.setSelected(false);
        tueCheckBox.setSelected(false);
        wedCheckBox.setSelected(false);
        thuCheckBox.setSelected(false);
        friCheckBox.setSelected(false);
        satCheckBox.setSelected(false);
        if ( days == null ) {
            everyDayRadioButton.doClick();
            return;
        }
        for( int aDay : days ) {
            if ( aDay == Schedule.SUNDAY ) {
                sunCheckBox.setSelected(true);
            }
            else if ( aDay == Schedule.MONDAY ) {
                monCheckBox.setSelected(true);
            }
            else if ( aDay == Schedule.TUESDAY ) {
                tueCheckBox.setSelected(true);
            }
            else if ( aDay == Schedule.WEDNESDAY ) {
                wedCheckBox.setSelected(true);
            }
            else if ( aDay == Schedule.THURSDAY ) {
                thuCheckBox.setSelected(true);
            }
            else if ( aDay == Schedule.FRIDAY ) {
                friCheckBox.setSelected(true);
            }
            else if ( aDay == Schedule.SATURDAY ) {
                satCheckBox.setSelected(true);
            }
        }
        if ( days.size() == 7 ) {
            daysButtonGroup.setSelected(everyDayRadioButton.getModel(), true);
//            everyDayRadioButton.doClick();
        }
        else if ( days.size() == 5 && !sunCheckBox.isSelected() && !satCheckBox.isSelected() ) {
            daysButtonGroup.setSelected(weekdayRadioButton.getModel(), true);
//            weekdayRadioButton.doClick();
        }
        else {
            daysButtonGroup.setSelected(customRadioButton.getModel(), true);
//            customRadioButton.doClick();
        }
    }

    private void toggleDays(boolean state) {
        sunCheckBox.setEnabled(state);
        monCheckBox.setEnabled(state);
        tueCheckBox.setEnabled(state);
        wedCheckBox.setEnabled(state);
        thuCheckBox.setEnabled(state);
        friCheckBox.setEnabled(state);
        satCheckBox.setEnabled(state);
    }

    /**
     * Notify listeners of change
     */
    private void notifyListenersOfChange() {
        if ( !scheduleBeingSet ) {
            fireChangeListenerStateChanged();
        }
    }

    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        daysButtonGroup = new javax.swing.ButtonGroup();
        instructions = new javax.swing.JLabel();
        namePanel = new javax.swing.JPanel();
        nameLabel = new javax.swing.JLabel();
        nameTextField = new javax.swing.JTextField();
        daysPanel = new javax.swing.JPanel();
        everyDayRadioButton = new javax.swing.JRadioButton();
        weekdayRadioButton = new javax.swing.JRadioButton();
        customRadioButton = new javax.swing.JRadioButton();
        sunCheckBox = new javax.swing.JCheckBox();
        monCheckBox = new javax.swing.JCheckBox();
        tueCheckBox = new javax.swing.JCheckBox();
        wedCheckBox = new javax.swing.JCheckBox();
        thuCheckBox = new javax.swing.JCheckBox();
        friCheckBox = new javax.swing.JCheckBox();
        satCheckBox = new javax.swing.JCheckBox();
        frequencyPanel = new javax.swing.JPanel();
        frequencySpinner = new javax.swing.JSpinner();
        frequencyComboBox = new javax.swing.JComboBox();
        everyLabel = new javax.swing.JLabel();
        displayLabel = new javax.swing.JLabel();
        betweenLabel = new javax.swing.JLabel();
        startTimeSpinner = new javax.swing.JSpinner();
        andLabel = new javax.swing.JLabel();
        endTimeSpinner = new javax.swing.JSpinner();

        org.jdesktop.application.ResourceMap resourceMap = org.jdesktop.application.Application.getInstance(org.robcash.apps.messagepopup.Main.class).getContext().getResourceMap(ScheduleEditor.class);
        instructions.setText(resourceMap.getString("instructions.text")); // NOI18N
        instructions.setName("instructions"); // NOI18N

        namePanel.setBorder(javax.swing.BorderFactory.createTitledBorder(resourceMap.getString("namePanel.border.title"))); // NOI18N
        namePanel.setName("namePanel"); // NOI18N

        nameLabel.setText(resourceMap.getString("nameLabel.text")); // NOI18N
        nameLabel.setName("nameLabel"); // NOI18N

        nameTextField.setName("nameTextField"); // NOI18N
        nameTextField.addFocusListener(new java.awt.event.FocusAdapter() {
            public void focusGained(java.awt.event.FocusEvent evt) {
                nameTextFieldFocusGained(evt);
            }
            public void focusLost(java.awt.event.FocusEvent evt) {
                nameTextFieldFocusLost(evt);
            }
        });

        javax.swing.GroupLayout namePanelLayout = new javax.swing.GroupLayout(namePanel);
        namePanel.setLayout(namePanelLayout);
        namePanelLayout.setHorizontalGroup(
            namePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(namePanelLayout.createSequentialGroup()
                .addContainerGap()
                .addComponent(nameLabel)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(nameTextField, javax.swing.GroupLayout.PREFERRED_SIZE, 179, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addContainerGap(154, Short.MAX_VALUE))
        );
        namePanelLayout.setVerticalGroup(
            namePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(namePanelLayout.createSequentialGroup()
                .addContainerGap()
                .addGroup(namePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(nameLabel)
                    .addComponent(nameTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addContainerGap(13, Short.MAX_VALUE))
        );

        daysPanel.setBorder(javax.swing.BorderFactory.createTitledBorder(resourceMap.getString("daysPanel.border.title"))); // NOI18N
        daysPanel.setName("daysPanel"); // NOI18N

        daysButtonGroup.add(everyDayRadioButton);
        everyDayRadioButton.setSelected(true);
        everyDayRadioButton.setText(resourceMap.getString("everyDayRadioButton.text")); // NOI18N
        everyDayRadioButton.setActionCommand(EVERY_DAY_BUTTON);
        everyDayRadioButton.setName("everyDayRadioButton"); // NOI18N
        everyDayRadioButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                daysSettingSelected(evt);
            }
        });

        daysButtonGroup.add(weekdayRadioButton);
        weekdayRadioButton.setText(resourceMap.getString("weekdayRadioButton.text")); // NOI18N
        weekdayRadioButton.setActionCommand(WEEKDAYS_BUTTON);
        weekdayRadioButton.setName("weekdayRadioButton"); // NOI18N
        weekdayRadioButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                daysSettingSelected(evt);
            }
        });

        daysButtonGroup.add(customRadioButton);
        customRadioButton.setText(resourceMap.getString("customRadioButton.text")); // NOI18N
        customRadioButton.setActionCommand(CUSTOM_DAYS_BUTTON);
        customRadioButton.setName("customRadioButton"); // NOI18N
        customRadioButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                daysSettingSelected(evt);
            }
        });

        sunCheckBox.setText(resourceMap.getString("sunCheckBox.text")); // NOI18N
        sunCheckBox.setEnabled(false);
        sunCheckBox.setName("sunCheckBox"); // NOI18N
        sunCheckBox.addItemListener(new java.awt.event.ItemListener() {
            public void itemStateChanged(java.awt.event.ItemEvent evt) {
                dayCheckBoxItemStateChanged(evt);
            }
        });

        monCheckBox.setText(resourceMap.getString("monCheckBox.text")); // NOI18N
        monCheckBox.setEnabled(false);
        monCheckBox.setName("monCheckBox"); // NOI18N
        monCheckBox.addItemListener(new java.awt.event.ItemListener() {
            public void itemStateChanged(java.awt.event.ItemEvent evt) {
                dayCheckBoxItemStateChanged(evt);
            }
        });

        tueCheckBox.setText(resourceMap.getString("tueCheckBox.text")); // NOI18N
        tueCheckBox.setEnabled(false);
        tueCheckBox.setName("tueCheckBox"); // NOI18N
        tueCheckBox.addItemListener(new java.awt.event.ItemListener() {
            public void itemStateChanged(java.awt.event.ItemEvent evt) {
                dayCheckBoxItemStateChanged(evt);
            }
        });

        wedCheckBox.setText(resourceMap.getString("wedCheckBox.text")); // NOI18N
        wedCheckBox.setEnabled(false);
        wedCheckBox.setName("wedCheckBox"); // NOI18N
        wedCheckBox.addItemListener(new java.awt.event.ItemListener() {
            public void itemStateChanged(java.awt.event.ItemEvent evt) {
                dayCheckBoxItemStateChanged(evt);
            }
        });

        thuCheckBox.setText(resourceMap.getString("thuCheckBox.text")); // NOI18N
        thuCheckBox.setEnabled(false);
        thuCheckBox.setName("thuCheckBox"); // NOI18N
        thuCheckBox.addItemListener(new java.awt.event.ItemListener() {
            public void itemStateChanged(java.awt.event.ItemEvent evt) {
                dayCheckBoxItemStateChanged(evt);
            }
        });

        friCheckBox.setText(resourceMap.getString("friCheckBox.text")); // NOI18N
        friCheckBox.setEnabled(false);
        friCheckBox.setName("friCheckBox"); // NOI18N
        friCheckBox.addItemListener(new java.awt.event.ItemListener() {
            public void itemStateChanged(java.awt.event.ItemEvent evt) {
                dayCheckBoxItemStateChanged(evt);
            }
        });

        satCheckBox.setText(resourceMap.getString("satCheckBox.text")); // NOI18N
        satCheckBox.setEnabled(false);
        satCheckBox.setName("satCheckBox"); // NOI18N
        satCheckBox.addItemListener(new java.awt.event.ItemListener() {
            public void itemStateChanged(java.awt.event.ItemEvent evt) {
                dayCheckBoxItemStateChanged(evt);
            }
        });

        javax.swing.GroupLayout daysPanelLayout = new javax.swing.GroupLayout(daysPanel);
        daysPanel.setLayout(daysPanelLayout);
        daysPanelLayout.setHorizontalGroup(
            daysPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(daysPanelLayout.createSequentialGroup()
                .addContainerGap()
                .addGroup(daysPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(everyDayRadioButton)
                    .addComponent(weekdayRadioButton)
                    .addComponent(customRadioButton)
                    .addGroup(daysPanelLayout.createSequentialGroup()
                        .addGap(21, 21, 21)
                        .addComponent(sunCheckBox)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                        .addComponent(monCheckBox)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                        .addComponent(tueCheckBox)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                        .addComponent(wedCheckBox)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                        .addComponent(thuCheckBox)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                        .addComponent(friCheckBox)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                        .addComponent(satCheckBox)))
                .addContainerGap(36, Short.MAX_VALUE))
        );
        daysPanelLayout.setVerticalGroup(
            daysPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(daysPanelLayout.createSequentialGroup()
                .addComponent(everyDayRadioButton)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(weekdayRadioButton)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(customRadioButton)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addGroup(daysPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(sunCheckBox)
                    .addComponent(monCheckBox)
                    .addComponent(tueCheckBox)
                    .addComponent(wedCheckBox)
                    .addComponent(thuCheckBox)
                    .addComponent(friCheckBox)
                    .addComponent(satCheckBox))
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );

        frequencyPanel.setBorder(javax.swing.BorderFactory.createTitledBorder(resourceMap.getString("frequencyPanel.border.title"))); // NOI18N
        frequencyPanel.setName("frequencyPanel"); // NOI18N

        frequencySpinner.setModel(new javax.swing.SpinnerNumberModel(Integer.valueOf(1), Integer.valueOf(1), null, Integer.valueOf(1)));
        frequencySpinner.setName("frequencySpinner"); // NOI18N
        frequencySpinner.addChangeListener(new javax.swing.event.ChangeListener() {
            public void stateChanged(javax.swing.event.ChangeEvent evt) {
                frequencySpinnerStateChanged(evt);
            }
        });

        frequencyComboBox.setModel(periodIntervals);
        frequencyComboBox.setName("frequencyComboBox"); // NOI18N
        frequencyComboBox.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                periodChanged(evt);
            }
        });

        everyLabel.setText(resourceMap.getString("everyLabel.text")); // NOI18N
        everyLabel.setName("everyLabel"); // NOI18N

        displayLabel.setText(resourceMap.getString("displayLabel.text")); // NOI18N
        displayLabel.setName("displayLabel"); // NOI18N

        betweenLabel.setText(resourceMap.getString("betweenLabel.text")); // NOI18N
        betweenLabel.setName("betweenLabel"); // NOI18N

        startTimeSpinner.setModel(new javax.swing.SpinnerDateModel(new java.util.Date(1230613200000L), null, null, java.util.Calendar.HOUR));
        startTimeSpinner.setEditor(new javax.swing.JSpinner.DateEditor(startTimeSpinner, "h:mm a"));
        startTimeSpinner.setName("startTimeSpinner"); // NOI18N
        startTimeSpinner.addChangeListener(new javax.swing.event.ChangeListener() {
            public void stateChanged(javax.swing.event.ChangeEvent evt) {
                timeChanged(evt);
            }
        });

        andLabel.setText(resourceMap.getString("andLabel.text")); // NOI18N
        andLabel.setName("andLabel"); // NOI18N

        endTimeSpinner.setModel(new javax.swing.SpinnerDateModel(new java.util.Date(1230699600000L), null, null, java.util.Calendar.HOUR));
        endTimeSpinner.setEditor(new javax.swing.JSpinner.DateEditor(endTimeSpinner, "h:mm a"));
        endTimeSpinner.setName("endTimeSpinner"); // NOI18N
        endTimeSpinner.addChangeListener(new javax.swing.event.ChangeListener() {
            public void stateChanged(javax.swing.event.ChangeEvent evt) {
                timeChanged(evt);
            }
        });

        javax.swing.GroupLayout frequencyPanelLayout = new javax.swing.GroupLayout(frequencyPanel);
        frequencyPanel.setLayout(frequencyPanelLayout);
        frequencyPanelLayout.setHorizontalGroup(
            frequencyPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(frequencyPanelLayout.createSequentialGroup()
                .addContainerGap()
                .addGroup(frequencyPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(frequencyPanelLayout.createSequentialGroup()
                        .addComponent(displayLabel)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(frequencySpinner, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(everyLabel)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(frequencyComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                    .addGroup(frequencyPanelLayout.createSequentialGroup()
                        .addComponent(betweenLabel)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(startTimeSpinner, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(andLabel)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(endTimeSpinner, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)))
                .addContainerGap(92, Short.MAX_VALUE))
        );
        frequencyPanelLayout.setVerticalGroup(
            frequencyPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(frequencyPanelLayout.createSequentialGroup()
                .addGroup(frequencyPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(displayLabel)
                    .addComponent(frequencySpinner, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(everyLabel)
                    .addComponent(frequencyComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addGroup(frequencyPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(betweenLabel)
                    .addComponent(startTimeSpinner, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(andLabel)
                    .addComponent(endTimeSpinner, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
        this.setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(instructions, javax.swing.GroupLayout.PREFERRED_SIZE, 386, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(namePanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .addComponent(daysPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .addComponent(frequencyPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
                .addContainerGap())
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addGap(14, 14, 14)
                .addComponent(instructions)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(namePanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(daysPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(frequencyPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addGap(15, 15, 15))
        );
    }// </editor-fold>//GEN-END:initComponents

    private void daysSettingSelected(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_daysSettingSelected
        toggleDays(CUSTOM_DAYS_BUTTON.equals(evt.getActionCommand()));
        notifyListenersOfChange();
    }//GEN-LAST:event_daysSettingSelected

    private void dayCheckBoxItemStateChanged(java.awt.event.ItemEvent evt) {//GEN-FIRST:event_dayCheckBoxItemStateChanged
        notifyListenersOfChange();
}//GEN-LAST:event_dayCheckBoxItemStateChanged

    private void nameTextFieldFocusGained(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_nameTextFieldFocusGained
        preEditScheduleName = nameTextField.getText();
    }//GEN-LAST:event_nameTextFieldFocusGained

    private void nameTextFieldFocusLost(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_nameTextFieldFocusLost
        String postEditScheduleName = nameTextField.getText();
        if ( (postEditScheduleName != null && !postEditScheduleName.equals(preEditScheduleName)) ||
        (postEditScheduleName == null && preEditScheduleName != null) ) {
            // schedule name changed
            notifyListenersOfChange();
        }
    }//GEN-LAST:event_nameTextFieldFocusLost

    private void frequencySpinnerStateChanged(javax.swing.event.ChangeEvent evt) {//GEN-FIRST:event_frequencySpinnerStateChanged
        notifyListenersOfChange();
    }//GEN-LAST:event_frequencySpinnerStateChanged

    private void timeChanged(javax.swing.event.ChangeEvent evt) {//GEN-FIRST:event_timeChanged
        notifyListenersOfChange();
    }//GEN-LAST:event_timeChanged

    private void periodChanged(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_periodChanged
        notifyListenersOfChange();
    }//GEN-LAST:event_periodChanged


    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JLabel andLabel;
    private javax.swing.JLabel betweenLabel;
    private javax.swing.JRadioButton customRadioButton;
    private javax.swing.ButtonGroup daysButtonGroup;
    private javax.swing.JPanel daysPanel;
    private javax.swing.JLabel displayLabel;
    private javax.swing.JSpinner endTimeSpinner;
    private javax.swing.JRadioButton everyDayRadioButton;
    private javax.swing.JLabel everyLabel;
    private javax.swing.JComboBox frequencyComboBox;
    private javax.swing.JPanel frequencyPanel;
    private javax.swing.JSpinner frequencySpinner;
    private javax.swing.JCheckBox friCheckBox;
    private javax.swing.JLabel instructions;
    private javax.swing.JCheckBox monCheckBox;
    private javax.swing.JLabel nameLabel;
    private javax.swing.JPanel namePanel;
    private javax.swing.JTextField nameTextField;
    private javax.swing.JCheckBox satCheckBox;
    private javax.swing.JSpinner startTimeSpinner;
    private javax.swing.JCheckBox sunCheckBox;
    private javax.swing.JCheckBox thuCheckBox;
    private javax.swing.JCheckBox tueCheckBox;
    private javax.swing.JCheckBox wedCheckBox;
    private javax.swing.JRadioButton weekdayRadioButton;
    // End of variables declaration//GEN-END:variables

}
